/**
  ******************************************************************************
  * @file    main.c
  * @author  AE Team
  * @version 1.0.3
  * @date    2024-05-28
  * @brief   演示使用VC对ATIM进行刹车。
  *          ATIM的CH3/CH3N通道输出带有死区时间的互补PWM信号，Break源选择为VC2，
  *          刹车后CH3输出低电平 CH3N输出高电平，解除刹车后PWM自动输出。
  *
  *          ATIM_CH3      :  PA03
  *          ATIM_CH3N     :  PA06
  *          VC2P = VC2_IN2:  PB02
  *          VC2OUT        :  PA04
  *          PCLK的频率为8MHz, ATIM预分频8, 溢出周期100uS, 互补PWM输出频率10KHz
  *
  * @note    硬件平台：SYM32L010_StartKit_V1.0
  *          接线说明：断开J9、J10、J13
  *                    短接J8、J11
  *                    向VC2P(PB02)提供可调节的电压，VC2输出高时触发刹车，VC2输出低时自动解除刹车。
  *                    请用用示波器观察PA01 / PA03 / PB02 / PA04的波形
  *
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2024 SIYIMicro.
  * All rights reserved.</center></h2>
  *
  *
  ******************************************************************************
  */


/******************************************************************************/
/* Include files                                                              */
/******************************************************************************/
#include "main.h"
#include "sym32l010_hal_sysctrl.h"
#include "sym32l010_hal_systick.h"
#include "sym32l010_hal_gpio.h"
#include "sym32l010_hal_atim.h"
#include "sym32l010_hal_vc.h"
#include "sym32l010_Startkit_board.h"


/******************************************************************************/
/* Local pre-processor symbols/macros ('#define')                             */
/******************************************************************************/

/******************************************************************************/
/* Global variable definitions (declared in header file with 'extern')        */
/******************************************************************************/
ATIM_HandleTypeDef hatim;

/******************************************************************************/
/* Local type definitions ('typedef')                                         */
/******************************************************************************/

/******************************************************************************/
/* Local function prototypes ('static')                                       */
/******************************************************************************/
static void VC2_Init(void);
static void ATIM_Init(void);

/******************************************************************************/
/* Local variable definitions ('static')                                      */
/******************************************************************************/

/******************************************************************************/
/* Local pre-processor symbols/macros ('#define')                             */
/******************************************************************************/

/******************************************************************************/
/* Function implementation - global ('extern') and local ('static')           */
/******************************************************************************/


/*******************************************************************************
 ** \brief  Main function of project
 **
 ** \return uint32_t return value, if needed
 **
 **
 ******************************************************************************/
int32_t main(void)
{
    // 初始化系统时钟
    HAL_SysCtrl_HSI_SetDiv(HSIOSC_TO_HSI8MHZ);

    // 初始化SysTick
    HAL_InitTick(8000000);

    // 初始化VC2
    VC2_Init();

    // 初始化ATIM
    ATIM_Init();

    while (1)
    {
        ;
    }
}


/*******************************************************************************
 * @brief  VC2初始化
 * @param  None
 * @retval None
 */
static void VC2_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    VC_InitTypeDef   VC_InitStruct;

    MemClr(&GPIO_InitStruct, sizeof(GPIO_InitStruct));
    MemClr(&VC_InitStruct,   sizeof(VC_InitStruct));

    // 使能外设时钟
    HAL_SYSCTRL_GPIOA_CLK_ENABLE();
    HAL_SYSCTRL_GPIOB_CLK_ENABLE();
    HAL_SYSCTRL_VC_CLK_ENABLE();

    //------------------------------------------------------------
    // 配置 VC2_INP 和 VC2_INN
    AFx_VC2IN2_PB02();                                                // VC2_IN2管脚配置
    HAL_VCReference_Enable(VCREF_VIN_VCAP, 8 - 1);                    // 分压比为8/8，输出电压为Vcore * 8 / 8

    //------------------------------------------------------------
    // 配置 VC2_OUT
    AFx_VC2OUT_PA04();
    GPIO_InitStruct.Pins = GPIO_PIN_4;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    HAL_GPIO_Init(SYM_GPIOA, &GPIO_InitStruct);

    //------------------------------------------------------------
    // 初始化 VC2
    VC_InitStruct.PChannel   = VC_PCHANNEL_IN2;                       // VCP选择IN2
    VC_InitStruct.NChannel   = VC_NCHANNEL_VCREF;                     // VCN选择VCREF
    VC_InitStruct.WindowEn   = VC_WINDOW_DISABLE;
    VC_InitStruct.Polarity   = VC_POLARITY_POSITIVE;
    VC_InitStruct.Hysteresis = VC_HYS_NONE;
    VC_InitStruct.Response   = VC_RESP_SLOW;
    VC_InitStruct.FilterClk  = VC_FILTERCLK_PCLK;
    VC_InitStruct.FilterTime = VC_FILTERTIME_FLTCLK8_N8;
    HAL_VC_Init(SYM_VC2, &VC_InitStruct);

    HAL_Delay(1);                                                     // 等待VC2建立完成

    HAL_VC_Enable(SYM_VC2);                                           // 使能VC2
}


/*******************************************************************************
 * @brief  ATIM初始化
 * @param  None
 * @retval None
 */
static void ATIM_Init(void)
{
    GPIO_InitTypeDef                 GPIO_InitStruct;
    ATIM_BreakDeadTimeConfigTypeDef  ATIM_BDTCfgStruct;
    ATIM_BreakInputConfigTypeDef     ATIM_BKInCfgStruct;
    MemClr(&GPIO_InitStruct,    sizeof(GPIO_InitStruct));
    MemClr(&ATIM_BDTCfgStruct,  sizeof(ATIM_BDTCfgStruct));
    MemClr(&ATIM_BKInCfgStruct, sizeof(ATIM_BKInCfgStruct));

    HAL_SYSCTRL_GPIOA_CLK_ENABLE();
    HAL_SYSCTRL_ATIM_CLK_ENABLE();

    //------------------------------------------------------------
    // 配置输出端口 ATIM_CH3/CH3N
    AFx_ATIMCH3_PA03();
    AFx_ATIMCH3N_PA06();
    HAL_GPIO_WritePins(SYM_GPIOA, GPIO_PIN_3 | GPIO_PIN_6, GPIO_PIN_RESET);
    GPIO_InitStruct.Pins = GPIO_PIN_3 | GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    HAL_GPIO_Init(SYM_GPIOA, &GPIO_InitStruct);

    //------------------------------------------------------------
    // 配置BKIN管脚
    AFx_ATIMBK_PA01();
    GPIO_InitStruct.Pins = GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULL_UP;
    HAL_GPIO_Init(SYM_GPIOA, &GPIO_InitStruct);

    //------------------------------------------------------------
    // 配置ATIM
    MemClr(&hatim, sizeof(hatim));

    hatim.Instance               = SYM_ATIM;
    hatim.Init.ClockDivision     = ATIM_CLOCKDIVISION_DIV1;
    hatim.Init.CounterMode       = ATIM_COUNTERMODE_UP;
    hatim.Init.Prescaler         = 8 - 1;
    hatim.Init.Period            = 100 - 1;
    hatim.Init.RepetitionCounter = 0;
    hatim.Init.AutoReloadPreload = ATIM_AUTORELOAD_PRELOAD_DISABLE;
    HAL_ATIM_Base_Init(&hatim);

    hatim.OcInit.OCMode       = ATIM_OCMODE_PWM1;
    hatim.OcInit.Pulse        = 50 - 1;
    hatim.OcInit.OCPolarity   = ATIM_OCPOLARITY_HIGH;
    hatim.OcInit.OCNPolarity  = ATIM_OCNPOLARITY_HIGH;
    hatim.OcInit.OCFastMode   = ATIM_OCFAST_ENABLE;
    hatim.OcInit.OCIdleState  = ATIM_OCIDLESTATE_RESET;               // 当MOE=0时经过死区时间输出0
    hatim.OcInit.OCNIdleState = ATIM_OCNIDLESTATE_SET;                // 当MOE=1时经过死区时间输出1
    HAL_ATIM_PWM_ConfigChannel(&hatim, &hatim.OcInit, ATIM_CHANNEL_3);

    // 配置死区时间及刹车状态
    ATIM_BDTCfgStruct.AutomaticOutput  = ATIM_AUTOMATICOUTPUT_ENABLE; // 自动输出使能
    ATIM_BDTCfgStruct.BreakFilter      = 6;                           // 刹车信号滤波设置
    ATIM_BDTCfgStruct.BreakPolarity    = ATIM_BREAKPOLARITY_HIGH;     // 刹车极性设置
    ATIM_BDTCfgStruct.BreakState       = ATIM_BREAK_ENABLE;           // 刹车使能
    ATIM_BDTCfgStruct.DeadTime         = 0xF;                         // 死区时间设置
    ATIM_BDTCfgStruct.LockLevel        = ATIM_LOCKLEVEL_OFF;          // 锁定级别配置
    ATIM_BDTCfgStruct.OffStateRunMode  = ATIM_OSSR_ENABLE;            // 运行模式下的关闭状态管脚由ATIM控制
    ATIM_BDTCfgStruct.OffStateIDLEMode = ATIM_OSSI_ENABLE;            // 空闲模式下的关闭状态管脚由ATIM控制
    HAL_ATIM_ConfigBreakDeadTime(&hatim, &ATIM_BDTCfgStruct);

    // 关闭来自管脚的刹车源
    ATIM_BKInCfgStruct.Source   = ATIM_BREAKINPUTSOURCE_BKIN;         // 刹车信号源设置
    ATIM_BKInCfgStruct.Polarity = ATIM_BREAKINPUTSOURCE_POLARITY_HIGH; // 刹车信号源极性, 高电平刹车
    ATIM_BKInCfgStruct.Enable   = ATIM_BREAKINPUTSOURCE_DISABLE;      // 刹车信号源使能
    HAL_ATIM_ConfigBreakInput(&hatim, ATIM_BREAKINPUT_BRK, &ATIM_BKInCfgStruct);

    // 使能来自VC2的刹车源
    ATIM_BKInCfgStruct.Source   = ATIM_BREAKINPUTSOURCE_VC2;          // 刹车信号源设置
    ATIM_BKInCfgStruct.Polarity = ATIM_BREAKINPUTSOURCE_POLARITY_HIGH; // 刹车信号源极性, 高电平刹车
    ATIM_BKInCfgStruct.Enable   = ATIM_BREAKINPUTSOURCE_ENABLE;       // 刹车信号源使能
    HAL_ATIM_ConfigBreakInput(&hatim, ATIM_BREAKINPUT_BRK, &ATIM_BKInCfgStruct);

    // 通道输出使能
    ATIM_CCxChannelCmd(hatim.Instance, ATIM_CHANNEL_3, ATIM_CCx_ENABLE);
    ATIM_CCxNChannelCmd(hatim.Instance, ATIM_CHANNEL_3, ATIM_CCxN_ENABLE);

    // 使能ATIM
    HAL_ATIM_ENABLE(&hatim);

    // 主输出使能
    HAL_ATIM_MOE_ENABLE(&hatim);
}


/*******************************************************************************
 ** EOF (not truncated)
 ******************************************************************************/
#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
    /* USER CODE BEGIN */
    /* User can add his own implementation to report the file name and line number,
       tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    /* USER CODE END */
}
#endif /* USE_FULL_ASSERT */


/************************ (C) COPYRIGHT SIYIMicro *****END OF FILE*************/
